/*******************************************************************************
 * @author scl
 * @email shchlu188@163.com
 ******************************************************************************/

#include "esp8266_service.h"
#include "module_esp8266.h"
#include "modbus_slave.h"
#include "bsp.h"
/**
 * @brief 尝试运行
 * */
#define try_cnt_run(func, cnt) \
    do{                          \
        bool flag = false;     \
        for (int i = 0; i < cnt; ++i) {\
            if (func){         \
                flag=true;     \
                break;\
            }                      \
        }                      \
        if(!flag) return flag; \
    }while(0)
/**
 * @brief 禁止接收数据(静态内联函数)
 */
sys_force_static_inline void esp_disable_rec() {
    UART_DISABLE_IT(USART3, UART_IT_RXNE);
}

sys_force_static_inline void esp_enable_rec() {
    UART_ENABLE_IT(USART3, UART_IT_RXNE);
}

bool esp_sta_tcp_server_init(void) {
    esp_ps("--esp_sta_tcp_server_init start---\r\n");
    /*使能信号*/
    esp8266_ch_enable(true);
    /*测试AT指令*/
    try_cnt_run (esp8266_base_at_cmd_test(10, 500), 1);
    esp_ps("esp8266_base_at_cmd_test ok\r\n");
    /*动态分配IP地址*/
    try_cnt_run(esp8266_dhcp_cur_set(sta_mode, true, -1), TRY_CNT);
    /* 设置为STA模式 */
    try_cnt_run(esp8266_wifi_mode_cur_set(sta_mode, -1), TRY_CNT);
    esp_ps("esp8266_mode_cur_set ok\r\n");
    /* 设备本地设备ip*/
    try_cnt_run(esp8266_ip_sta_cur_set(LOCAL_SERVER_IP, NULL, NULL, -1), TRY_CNT);
    esp_ps("esp8266_ip_sta_cur_set ok\r\n");
    /*连接WiFi*/
    try_cnt_run (esp8266_wifi_join_cur_set(WIFI_SSID, WIFI_PWD, NULL, -1), TRY_CNT);
    esp_ps("esp8266_wifi_join_cur_set ok\r\n");
    /*允许多连接*/
    try_cnt_run (esp8266_mul_connect_set(true, -1), TRY_CNT);
    esp_ps("esp8266_mul_connect_set ok\r\n");
    /*开启服务器模式*/
    try_cnt_run (esp8266_server_tcp_start(true, LOCAL_SERVER_PORT, -1), TRY_CNT);
    esp_ps("esp8266_server_tcp_start ok\r\n");
    /*设置服务器链接超时时间*/
    try_cnt_run (esp8266_server_tcp_timeout_set(20, -1), TRY_CNT);
    esp_ps("esp8266_server_tcp_timeout_set ok\r\n");

    esp_ps("--esp_sta_tcp_server_init end---\r\n");

    return true;
}

bool esp_sta_tcp_server_get_ip(char *dstIp, uint8_t len) {
    esp_ps("--esp_sta_tcp_server_get_ip start---\r\n");
    try_cnt_run (esp8266_ip_sta_inquire(dstIp, len, -1), TRY_CNT);
    esp_ps("--esp_sta_tcp_server_get_ip end---\r\n");
    return true;
}
/**
 * @brief 解析接收的数据
 * @param rec_data 接收的数据
 * @param no_id socket id
 * @param data_len 发送的数据长度
 * @return 实际数据的位置
 */
sys_force_static_inline char *parse_rec_data(char *rec_data, uint8_t *no_id, uint16_t *data_len) {
    static char *pre_str = "+IPD,";
    char *p_data = strstr(rec_data, pre_str);
    // 数据解析错误 +IPD,0,2:12
    if (!p_data) return false;
    /*跳过前缀*/
    p_data += strlen(pre_str);
    /*解析socket id 号*/
    *no_id = strtol(p_data, &p_data, 10);
    if (!*p_data) return false;
    /*解析数据长度 */
    *data_len = strtol(p_data + 1, &p_data, 10);
    if (!*p_data) return false;
    /*获取数据*/
    p_data += 1;
    return p_data;
}

/*当前通讯的socket id*/
volatile uint8_t cur_socket_id;

bool esp_sta_tcp_server_request_handle(char *data, uint16_t len) {
    /* 禁止esp多个客户端同时发送数据 */
    uint16_t data_len = 0;/*实际客户端发送的数据长度*/
    uint8_t socket_id;/*实际客户端连接的端口号*/
    bool result_flag = true;
    /*禁止接收,保证同一时间只只处理一个请求 */
    esp_disable_rec();
    /*实际客户端发送的数据位置*/
    char *p_data = parse_rec_data(data, &socket_id, &data_len);
    if (p_data) {
        // todo 这里就是做业务逻辑控制的地方,目前只是回显
        esp_ps("parse_rec_data:%d %d %s\r\n", socket_id, data_len, p_data);
        cur_socket_id = socket_id;
        modbus_poll_rec((uint8_t *) p_data, data_len);
//        if (esp8266_server_tcp_send_to(socket_id, p_data, data_len, -1)) {
//            esp_ps("response ok\r\n");
//        } else {
//            esp_ps("response error\r\n");
//        }
    } else {
        result_flag = false;
    }
    /*清除这次的请求数据,保证下次数据为最新的*/
    esp8266_clear_buf();
    /*开启请求,保证同一时间只只处理一个请求 */
    esp_enable_rec();
    return result_flag;
}
